import cv2
import numpy as np

# 初始化摄像头
cap = cv2.VideoCapture(0)


# 特征计算函数
def calculate_features(contour):
    # 基础几何特征
    area = cv2.contourArea(contour)
    perimeter = cv2.arcLength(contour, True)

    # 凸包特征
    hull = cv2.convexHull(contour)
    hull_area = cv2.contourArea(hull)
    solidity = area / hull_area if hull_area > 0 else 0

    # 圆形度
    circularity = (4 * np.pi * area) / (perimeter ** 2) if perimeter > 0 else 0

    # Hu矩
    moments = cv2.moments(contour)
    hu = cv2.HuMoments(moments)
    hu1 = hu[0][0]

    return [area, perimeter, hull_area, solidity, circularity, hu1]


# 多特征分类器
def classify_gesture(features):
    area, perimeter, hull_area, solidity, circularity, hu1 = features
    # 石头判定条件
    rock_condition = (
            solidity > 0.82 and
            0.50 < circularity < 0.70 and
            0.17 < hu1 < 0.22
    )

    # 剪刀判定条件
    scissors_condition = (
            solidity < 0.8 and
            0.24 < circularity < 0.35 and
            0.23 < hu1 < 0.285
    )

    # 布判定条件
    paper_condition = (
            solidity < 0.8 and
            0.19 < hu1 < 0.245
    )

    if rock_condition:
        return "Rock", (0, 0, 255)  # 红色
    elif scissors_condition:
        return "Scissors", (0, 255, 0)  # 绿色
    elif paper_condition:
        return "Paper", (255, 0, 0)  # 蓝色
    else:
        return "Unknown", (0, 0, 0)


def main():
    while True:
        ret, frame = cap.read()
        if not ret:
            break

        # 预处理流程
        hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
        s_channel = hsv[:, :, 1]
        blurred = cv2.GaussianBlur(s_channel, (5, 5), 0)
        _, thresh = cv2.threshold(blurred, 50, 255, cv2.THRESH_BINARY)
        closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, np.ones((5, 5), np.uint8), iterations=3)

        # 轮廓检测
        contours, _ = cv2.findContours(closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

        if contours:
            max_contour = max(contours, key=cv2.contourArea)
            if cv2.contourArea(max_contour) > 50000:
                # 计算特征
                features = calculate_features(max_contour)
                # 分类并获取结果颜色
                gesture, color = classify_gesture(features)
                # 绘制轮廓和文本
                cv2.drawContours(frame, [max_contour], -1, color, 3)
                cv2.putText(frame, gesture, (50, 100),
                            cv2.FONT_HERSHEY_SIMPLEX, 3, color, 3)
                with open('features.txt', 'w') as f:
                    f.write(f'{features}')


        # 显示窗口
        cv2.imshow('Gesture Recognition', frame)

        if cv2.waitKey(1) == 27:  # ESC退出
            break

    cap.release()
    cv2.destroyAllWindows()


if __name__ == '__main__':
    main()